// Class IpAddress
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The IpAddress class represents an IPv4 address. It allows application 
// programmers to easily create/store IP addresses. IpAddress class instances
// can be instantiated by giving a string representation of an IP address to the
// constructor or a hostname. Hostnames given to the constructor will be 
// automatically resolved.
 

#ifndef IPADDRESS_H
#define	IPADDRESS_H

#include "AddressResolutionException.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string>
using namespace std;

enum ByteOrder { HOST, NETWORK };

class IpAddress
{
private:
    
    const static unsigned int IP_ADDRESS_ANY = 0u;    
    unsigned int ipAddrHostOrder;
    unsigned int ipAddrNetworkOrder;
    string ipString;
    
    void assignIpFromHostOrderInteger(unsigned int ipAddress);
    void assignIpFromNetworkOrderInteger(unsigned int ipAddress);
    void assignIpStringFromNetworkOrderAddress(unsigned int ipAddress);
    void throwExceptionOnAddressResolutionError(int errorCode);
    
public:
    
    // Represents the "0.0.0.0" IPv4 address
    const static IpAddress ANY;
    
    IpAddress();
    
    // Create an IpAddress instance using an IP address in integer form with the
    // specified byte ordering. Default order is network order.
    // Parameter(s) :
    // ipAddress  ---  The IP address in integer form
    IpAddress(unsigned int ipAddress, ByteOrder byteOrder=NETWORK);
    
    // Create an IpAddress instance using an IP address string or hostname
    // Parameter(s) :
    // ipAddressOrHostname  ---  The IP address in string form or a hostname
    IpAddress(const string & ipAddressOrHostname);
    
    // Gets the integer form of the IP address represented by this instance
    // in host order
    unsigned int getIpAddressInHostOrder() const;
    
    // Gets the integer form of the IP address represented by this instance
    // in network order
    unsigned int getIpAddressInNetworkOrder() const;
    
    // Gets the string form of the IP address represented by this instance
    const string & toString() const;
    
    bool operator==(const IpAddress & ipAddress) const;
    
    bool operator!=(const IpAddress & ipAddress) const;
};
#endif

